package com.demo.utils;
import com.alibaba.fastjson.JSONObject;
import com.tiangong.framework.bo.CDO;
import com.tiangong.framework.bo.Return;
import com.tiangong.framework.util.redis.util.HttpsUtils;
import org.apache.log4j.Logger;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.spec.SecretKeySpec;
import com.alibaba.fastjson.JSON;


import java.nio.charset.StandardCharsets;
import java.security.spec.AlgorithmParameterSpec;

public class WxUtility
{
	private static Logger logger=Logger.getLogger(WxUtility.class);
	private static String URL_WX_ACCESS_TOKEN="https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
	/**
	 * 获取微信用户信息
	 * @param sWxAuthCode
	 * @param sAppId
	 * @param sAppSecret
	 * @param cdoResponse
	 * @return
	 */
	public static Return getUserInfoFromWx (String sWxAuthCode,String sAppId,String sAppSecret, CDO cdoResponse){
		String OAUTHUSERINFO="https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code";
		String path = OAUTHUSERINFO.replace("APPID", sAppId);
		path = path.replace("SECRET", sAppSecret);
		path = path.replace("JSCODE", sWxAuthCode);
		String result = "";
		try {
			result=HttpsUtils.doPost(path);
		}catch(Exception e)
		{
			e.printStackTrace();
		}
		System.out.println(result);
		JSONObject object= JSONObject.parseObject(result);
		String openId = object.getString("openid")==null ? "" : object.getString("openid");//用户唯一标识
		String session_key = object.getString("session_key") == null ? "" : object.getString("session_key");// session_key
		String unionId = object.getString("unionid") == null ? "" : object.getString("unionid");// unionid
		cdoResponse.set("appId", sAppId);
		cdoResponse.set("openId", openId);
		cdoResponse.set("sessionKey", session_key);
		cdoResponse.set("unionId", unionId);
		if (object.containsKey("errcode")){
			return Return.valueOf(201,"请求失败",object);
		}
		return Return.valueOf(cdoResponse);
	}

	/**
	 * 获取微信用户信息
	 * 接口文档：https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
	 * @param sWxAuthCode
	 * @param sAppId
	 * @param sAppSecret
	 * @param cdoResponse
	 * @return
	 */
	public static Return getWXUserAuthAccessToken (String sWxAuthCode,String sAppId,String sAppSecret, CDO cdoResponse){
		String path = WxUtility.URL_WX_ACCESS_TOKEN.replace("APPID", sAppId).replace("SECRET", sAppSecret).replace("CODE", sWxAuthCode);
		//从微信服务器获取openid
		String result = "";
		try {
			result=HttpsUtils.doPost(path);
		}catch(Exception e)
		{
			e.printStackTrace();
		}
		System.out.println(result);
		return Return.SUCCESS;
	}

	public static String getAccessTokenURL="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";//获取token
	public static String getTemplateList="https://api.weixin.qq.com/cgi-bin/wxopen/template/list?access_token=ACCESS_TOKEN";//
	public static String URL_PUSH_WX_NOTICE_XCX="https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN";
	public static String URL_PUSH_WX_NOTICE_MP="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN\n";

	public static String getAccessToken(String sAppId,String sAppSecret) {
		String requestUrl = WxUtility.getAccessTokenURL.replace("APPID", sAppId).replace("APPSECRET", sAppSecret);
		// 发起GET请求获取凭证
		String result="";
		try {
			result = HttpsUtils.doGet(requestUrl);
		}catch (Exception e)
		{
			e.printStackTrace();
		}
		if(result.length()!=0)
		{
			CDO cdoResult= CDO.parseObject(result);
			if(cdoResult.containsKey("access_token"))
			{
				return cdoResult.getString("access_token");
			}
		}
		return result;
	}


	/**
	 * 解密用户敏感数据获取用户信息
	 * @param encryptedData	包括敏感数据在内的完整用户信息的加密数据
	 * @param session_key	数据进行加密签名的密钥
	 * @param iv	加密算法的初始向量
	 * @return
	 */
	public static CDO getWxUserInfo(String encryptedData, String session_key, String iv)
	{
		String userInfo = "";
		try
		{
			byte[] dataByte = encryptedData.getBytes();
			// 加密秘钥
			byte[] keyByte =  session_key.getBytes();
			// 偏移量
			byte[] ivByte =  iv.getBytes();

			byte[] resultByte  = AesCbcUtil.decrypt(dataByte,  keyByte, ivByte);
			if (null != resultByte && resultByte.length > 0) {
				userInfo = new String(resultByte, "UTF-8");
				logger.info("解密用户敏感数据获取用户信息：" + userInfo);
				return CDO.parseRPCJSONString(userInfo);
			}
		} catch (Exception e) {
			try{
				encryptedData = encryptedData.replaceAll(" ", "+");
				iv = iv.replaceAll(" ", "+");
				// 被加密的数据
				byte[] dataByte = encryptedData.getBytes();
				// 加密秘钥
				byte[] keyByte =  session_key.getBytes();
				// 偏移量
				byte[] ivByte =  iv.getBytes();

				byte[] resultByte  = AesCbcUtil.decrypt(dataByte,  keyByte, ivByte);
				if (null != resultByte && resultByte.length > 0) {
					userInfo = new String(resultByte, "UTF-8");
					logger.info("解密用户敏感数据获取用户信息：" + userInfo);
					return CDO.parseRPCJSONString(userInfo);
				}
			} catch (Exception ex) {
				logger.error("解密用户敏感数据获取用户信息：encryptedData=" + encryptedData);
				logger.error("解密用户敏感数据获取用户信息：session_key=" + session_key);
				logger.error("解密用户敏感数据获取用户信息：iv=" + iv);
				logger.error("解密用户敏感数据获取用户信息：userInfo===" + userInfo);
				logger.error("解密用户敏感数据获取用户信息失败：" , ex);
			}
		}
		return null;
	}



	public static String decrypt(String encrypdata,String key, String iv) throws Exception {
		encrypdata = encrypdata.replaceAll(" ", "+");
		iv = iv.replaceAll(" ", "+");
		AlgorithmParameterSpec ivSpec = new IvParameterSpec(Base64.decodeBase64(iv));
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		SecretKeySpec keySpec = new SecretKeySpec(Base64.decodeBase64(key), "AES");
		cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
		String result = new String(cipher.doFinal(Base64.decodeBase64(encrypdata)), StandardCharsets.UTF_8);
		JSONObject jsonObject = JSON.parseObject(result);
		//解析解密后的字符串
		return jsonObject.getString("phoneNumber");
	}

}
